home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / Mesa-2.2 / src / pb.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-03-13  |  13.6 KB  |  418 lines

  1. /* $Id: pb.c,v 1.7 1997/02/09 19:53:43 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  2.2
  6.  * Copyright (C) 1995-1997  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: pb.c,v $
  26.  * Revision 1.7  1997/02/09 19:53:43  brianp
  27.  * now use TEXTURE_xD enable constants
  28.  *
  29.  * Revision 1.6  1997/02/09 18:43:14  brianp
  30.  * added GL_EXT_texture3D support
  31.  *
  32.  * Revision 1.5  1997/02/03 20:30:54  brianp
  33.  * added a few DEFARRAY macros for BeOS
  34.  *
  35.  * Revision 1.4  1997/01/28 22:17:44  brianp
  36.  * new RGBA mode logic op support
  37.  *
  38.  * Revision 1.3  1996/09/25 03:21:10  brianp
  39.  * added NO_DRAW_BIT support
  40.  *
  41.  * Revision 1.2  1996/09/15 14:18:37  brianp
  42.  * now use GLframebuffer and GLvisual
  43.  *
  44.  * Revision 1.1  1996/09/13 01:38:16  brianp
  45.  * Initial revision
  46.  *
  47.  */
  48.  
  49.  
  50. /*
  51.  * Pixel buffer:
  52.  *
  53.  * As fragments are produced (by point, line, and bitmap drawing) they
  54.  * are accumlated in a buffer.  When the buffer is full or has to be
  55.  * flushed (glEnd), we apply all enabled rasterization functions to the
  56.  * pixels and write the results to the display buffer.  The goal is to
  57.  * maximize the number of pixels processed inside loops and to minimize
  58.  * the number of function calls.
  59.  */
  60.  
  61.  
  62.  
  63. #include <stdlib.h>
  64. #include <string.h>
  65. #include "alpha.h"
  66. #include "alphabuf.h"
  67. #include "blend.h"
  68. #include "depth.h"
  69. #include "fog.h"
  70. #include "logic.h"
  71. #include "macros.h"
  72. #include "masking.h"
  73. #include "pb.h"
  74. #include "scissor.h"
  75. #include "stencil.h"
  76. #include "texture.h"
  77. #include "types.h"
  78.  
  79.  
  80.  
  81. /*
  82.  * When the pixel buffer is full, or needs to be flushed, call this
  83.  * function.  All the pixels in the pixel buffer will be subjected
  84.  * to texturing, scissoring, stippling, alpha testing, stenciling,
  85.  * depth testing, blending, and finally written to the frame buffer.
  86.  */
  87. void gl_flush_pb( GLcontext *ctx )
  88. {
  89.    struct pixel_buffer* PB = ctx->PB;
  90.  
  91.    DEFARRAY(GLubyte,mask,PB_SIZE+4);   /* add 4 for manually unrolled loop, below */
  92.    DEFARRAY(GLubyte, rsave, PB_SIZE);
  93.    DEFARRAY(GLubyte, gsave, PB_SIZE);
  94.    DEFARRAY(GLubyte, bsave, PB_SIZE);
  95.    DEFARRAY(GLubyte, asave, PB_SIZE);
  96.  
  97.    if (PB->count==0)  goto CleanUp;
  98.  
  99.    /* initialize mask array and clip pixels simultaneously */
  100.    {
  101.       GLint xmin = ctx->Buffer->Xmin;
  102.       GLint xmax = ctx->Buffer->Xmax;
  103.       GLint ymin = ctx->Buffer->Ymin;
  104.       GLint ymax = ctx->Buffer->Ymax;
  105.       GLint *x = PB->x;
  106.       GLint *y = PB->y;
  107.       GLuint i = 0;
  108.       /* manually unrolled loop, OK to go past PB->count */
  109.       do {
  110.          mask[i] = (x[i]>=xmin) & (x[i]<=xmax) & (y[i]>=ymin) & (y[i]<=ymax);
  111.          i++;
  112.          mask[i] = (x[i]>=xmin) & (x[i]<=xmax) & (y[i]>=ymin) & (y[i]<=ymax);
  113.          i++;
  114.          mask[i] = (x[i]>=xmin) & (x[i]<=xmax) & (y[i]>=ymin) & (y[i]<=ymax);
  115.          i++;
  116.          mask[i] = (x[i]>=xmin) & (x[i]<=xmax) & (y[i]>=ymin) & (y[i]<=ymax);
  117.          i++;
  118.       } while (i<PB->count);
  119.    }
  120.  
  121.    if (ctx->Visual->RGBAflag) {
  122.       /* RGBA COLOR PIXELS */
  123.       if (PB->mono && ctx->MutablePixels) {
  124.      /* Copy flat color to all pixels */
  125.          MEMSET( PB->r, PB->color[0], PB->count );
  126.          MEMSET( PB->g, PB->color[1], PB->count );
  127.          MEMSET( PB->b, PB->color[2], PB->count );
  128.          MEMSET( PB->a, PB->color[3], PB->count );
  129.       }
  130.  
  131.       /* If each pixel can be of a different color... */
  132.       if (ctx->MutablePixels || !PB->mono) {
  133.  
  134.      if (ctx->Texture.Enabled & TEXTURE_3D) {
  135.             /* TODO: need texture lambda valus */
  136.         gl_texture_pixels_3d( ctx, PB->count, PB->s, PB->t, PB->u, NULL,
  137.                                   PB->r, PB->g, PB->b, PB->a);
  138.      }
  139.      else if (ctx->Texture.Enabled & TEXTURE_2D) {
  140.             /* TODO: need texture lambda valus */
  141.         gl_texture_pixels_2d( ctx, PB->count, PB->s, PB->t, NULL,
  142.                                   PB->r, PB->g, PB->b, PB->a);
  143.      }
  144.      else if (ctx->Texture.Enabled & TEXTURE_1D) {
  145.            /* TODO: need texture lambda values */
  146.         gl_texture_pixels_1d( ctx, PB->count, PB->s, NULL,
  147.                                   PB->r, PB->g, PB->b, PB->a );
  148.      }
  149.  
  150.      if (ctx->Fog.Enabled
  151.              && (ctx->Hint.Fog==GL_NICEST || PB->primitive==GL_BITMAP)) {
  152.         gl_fog_color_pixels( ctx, PB->count, PB->z,
  153.                  PB->r, PB->g, PB->b, PB->a );
  154.      }
  155.  
  156.          /* Scissoring already done above */
  157.  
  158.      if (ctx->Color.AlphaEnabled) {
  159.         if (gl_alpha_test( ctx, PB->count, PB->a, mask )==0) {
  160.            goto CleanUp;
  161.         }
  162.      }
  163.  
  164.      if (ctx->Stencil.Enabled) {
  165.         /* first stencil test */
  166.         if (gl_stencil_pixels( ctx, PB->count, PB->x, PB->y, mask )==0) {
  167.            goto CleanUp;
  168.         }
  169.         /* depth buffering w/ stencil */
  170.         gl_depth_stencil_pixels( ctx, PB->count, PB->x, PB->y, PB->z, mask );
  171.      }
  172.      else if (ctx->Depth.Test) {
  173.         /* regular depth testing */
  174.         (*ctx->Driver.DepthTestPixels)( ctx, PB->count, PB->x, PB->y, PB->z, mask );
  175.      }
  176.  
  177.          if (ctx->RasterMask & NO_DRAW_BIT) {
  178.             goto CleanUp;
  179.          }
  180.  
  181.          if (ctx->RasterMask & FRONT_AND_BACK_BIT) {
  182.             /* make a copy of the colors */
  183.             MEMCPY( rsave, PB->r, PB->count * sizeof(GLubyte) );
  184.             MEMCPY( gsave, PB->r, PB->count * sizeof(GLubyte) );
  185.             MEMCPY( bsave, PB->r, PB->count * sizeof(GLubyte) );
  186.             MEMCPY( asave, PB->r, PB->count * sizeof(GLubyte) );
  187.          }
  188.  
  189.          if (ctx->Color.SWLogicOpEnabled) {
  190.             gl_logicop_rgba_pixels( ctx, PB->count, PB->x, PB->y,
  191.                                     PB->r, PB->g, PB->b, PB->a, mask);
  192.          }
  193.          else if (ctx->Color.BlendEnabled) {
  194.             gl_blend_pixels( ctx, PB->count, PB->x, PB->y,
  195.                              PB->r, PB->g, PB->b, PB->a, mask);
  196.          }
  197.  
  198.          if (ctx->Color.SWmasking) {
  199.             gl_mask_color_pixels( ctx, PB->count, PB->x, PB->y,
  200.                                   PB->r, PB->g, PB->b, PB->a, mask );
  201.          }
  202.  
  203.          /* write pixels */
  204.          (*ctx->Driver.WriteColorPixels)( ctx, PB->count, PB->x, PB->y,
  205.                                           PB->r, PB->g, PB->b, PB->a, mask );
  206.          if (ctx->RasterMask & ALPHABUF_BIT) {
  207.             gl_write_alpha_pixels( ctx, PB->count, PB->x, PB->y, PB->a, mask );
  208.          }
  209.  
  210.          if (ctx->RasterMask & FRONT_AND_BACK_BIT) {
  211.             /*** Also draw to back buffer ***/
  212.             (*ctx->Driver.SetBuffer)( ctx, GL_BACK );
  213.             if (ctx->Color.SWLogicOpEnabled) {
  214.                gl_logicop_rgba_pixels( ctx, PB->count, PB->x, PB->y,
  215.                                        PB->r, PB->g, PB->b, PB->a, mask);
  216.             }
  217.             else if (ctx->Color.BlendEnabled) {
  218.                gl_blend_pixels( ctx, PB->count, PB->x, PB->y,
  219.                                 rsave, gsave, bsave, asave, mask );
  220.             }
  221.             if (ctx->Color.SWmasking) {
  222.                gl_mask_color_pixels( ctx, PB->count, PB->x, PB->y,
  223.                                      rsave, gsave, bsave, asave, mask);
  224.             }
  225.             (*ctx->Driver.WriteColorPixels)( ctx, PB->count, PB->x, PB->y,
  226.                                              rsave, gsave, bsave, asave, mask);
  227.             if (ctx->RasterMask & ALPHABUF_BIT) {
  228.                ctx->Buffer->Alpha = ctx->Buffer->BackAlpha;
  229.                gl_write_alpha_pixels( ctx, PB->count, PB->x, PB->y,
  230.                                       asave, mask );
  231.                ctx->Buffer->Alpha = ctx->Buffer->FrontAlpha;
  232.             }
  233.             (*ctx->Driver.SetBuffer)( ctx, GL_FRONT );
  234.             /*** ALL DONE ***/
  235.          }
  236.       }
  237.       else {
  238.      /* Same color for all pixels */
  239.  
  240.          /* Scissoring already done above */
  241.  
  242.      if (ctx->Color.AlphaEnabled) {
  243.         if (gl_alpha_test( ctx, PB->count, PB->a, mask )==0) {
  244.            goto CleanUp;
  245.         }
  246.      }
  247.  
  248.      if (ctx->Stencil.Enabled) {
  249.         /* first stencil test */
  250.         if (gl_stencil_pixels( ctx, PB->count, PB->x, PB->y, mask )==0) {
  251.            goto CleanUp;
  252.         }
  253.         /* depth buffering w/ stencil */
  254.         gl_depth_stencil_pixels( ctx, PB->count, PB->x, PB->y, PB->z, mask );
  255.      }
  256.      else if (ctx->Depth.Test) {
  257.         /* regular depth testing */
  258.         (*ctx->Driver.DepthTestPixels)( ctx, PB->count, PB->x, PB->y, PB->z, mask );
  259.      }
  260.  
  261.          if (ctx->RasterMask & NO_DRAW_BIT) {
  262.             goto CleanUp;
  263.          }
  264.  
  265.          /* write pixels */
  266.          {
  267.             GLubyte red, green, blue, alpha;
  268.             red   = PB->color[0];
  269.             green = PB->color[1];
  270.             blue  = PB->color[2];
  271.             alpha = PB->color[3];
  272.         (*ctx->Driver.Color)( ctx, red, green, blue, alpha );
  273.          }
  274.          (*ctx->Driver.WriteMonocolorPixels)( ctx, PB->count, PB->x, PB->y, mask );
  275.          if (ctx->RasterMask & ALPHABUF_BIT) {
  276.             gl_write_mono_alpha_pixels( ctx, PB->count, PB->x, PB->y,
  277.                                         PB->color[3], mask );
  278.          }
  279.  
  280.          if (ctx->RasterMask & FRONT_AND_BACK_BIT) {
  281.             /*** Also render to back buffer ***/
  282.             (*ctx->Driver.SetBuffer)( ctx, GL_BACK );
  283.             (*ctx->Driver.WriteMonocolorPixels)( ctx, PB->count, PB->x, PB->y, mask );
  284.             if (ctx->RasterMask & ALPHABUF_BIT) {
  285.                ctx->Buffer->Alpha = ctx->Buffer->BackAlpha;
  286.                gl_write_mono_alpha_pixels( ctx, PB->count, PB->x, PB->y,
  287.                                            PB->color[3], mask );
  288.                ctx->Buffer->Alpha = ctx->Buffer->FrontAlpha;
  289.             }
  290.             (*ctx->Driver.SetBuffer)( ctx, GL_FRONT );
  291.      }
  292.          /*** ALL DONE ***/
  293.       }
  294.    }
  295.    else {
  296.       /* COLOR INDEX PIXELS */
  297.  
  298.       /* If we may be writting pixels with different indexes... */
  299.       if (PB->mono && ctx->MutablePixels) {
  300.      /* copy index to all pixels */
  301.          GLuint n = PB->count, indx = PB->index;
  302.          GLuint *pbindex = PB->i;
  303.          do {
  304.         *pbindex++ = indx;
  305.             n--;
  306.      } while (n);
  307.       }
  308.  
  309.       if (ctx->MutablePixels || !PB->mono) {
  310.      /* Pixel color index may be modified */
  311.          GLuint isave[PB_SIZE];
  312.  
  313.      if (ctx->Fog.Enabled
  314.              && (ctx->Hint.Fog==GL_NICEST || PB->primitive==GL_BITMAP)) {
  315.         gl_fog_index_pixels( ctx, PB->count, PB->z, PB->i );
  316.      }
  317.  
  318.          /* Scissoring already done above */
  319.  
  320.      if (ctx->Stencil.Enabled) {
  321.         /* first stencil test */
  322.         if (gl_stencil_pixels( ctx, PB->count, PB->x, PB->y, mask )==0) {
  323.            goto CleanUp;
  324.         }
  325.         /* depth buffering w/ stencil */
  326.         gl_depth_stencil_pixels( ctx, PB->count, PB->x, PB->y, PB->z, mask );
  327.      }
  328.      else if (ctx->Depth.Test) {
  329.         /* regular depth testing */
  330.         (*ctx->Driver.DepthTestPixels)( ctx, PB->count, PB->x, PB->y, PB->z, mask );
  331.      }
  332.  
  333.          if (ctx->RasterMask & NO_DRAW_BIT) {
  334.             goto CleanUp;
  335.          }
  336.  
  337.          if (ctx->RasterMask & FRONT_AND_BACK_BIT) {
  338.             /* make a copy of the indexes */
  339.             MEMCPY( isave, PB->i, PB->count * sizeof(GLuint) );
  340.          }
  341.  
  342.          if (ctx->Color.SWLogicOpEnabled) {
  343.             gl_logicop_ci_pixels( ctx, PB->count, PB->x, PB->y, PB->i, mask );
  344.          }
  345.  
  346.          if (ctx->Color.SWmasking) {
  347.             gl_mask_index_pixels( ctx, PB->count, PB->x, PB->y, PB->i, mask );
  348.          }
  349.  
  350.          /* write pixels */
  351.          (*ctx->Driver.WriteIndexPixels)( ctx, PB->count, PB->x, PB->y,
  352.                                           PB->i, mask );
  353.  
  354.          if (ctx->RasterMask & FRONT_AND_BACK_BIT) {
  355.             /*** Also write to back buffer ***/
  356.             (*ctx->Driver.SetBuffer)( ctx, GL_BACK );
  357.             MEMCPY( PB->i, isave, PB->count * sizeof(GLuint) );
  358.             if (ctx->Color.SWLogicOpEnabled) {
  359.                gl_logicop_ci_pixels( ctx, PB->count, PB->x, PB->y, PB->i, mask );
  360.             }
  361.             if (ctx->Color.SWmasking) {
  362.                gl_mask_index_pixels( ctx, PB->count, PB->x, PB->y,
  363.                                      PB->i, mask );
  364.             }
  365.             (*ctx->Driver.WriteIndexPixels)( ctx, PB->count, PB->x, PB->y,
  366.                                              PB->i, mask );
  367.             (*ctx->Driver.SetBuffer)( ctx, GL_FRONT );
  368.          }
  369.  
  370.          /*** ALL DONE ***/
  371.       }
  372.       else {
  373.      /* Same color index for all pixels */
  374.  
  375.          /* Scissoring already done above */
  376.  
  377.      if (ctx->Stencil.Enabled) {
  378.         /* first stencil test */
  379.         if (gl_stencil_pixels( ctx, PB->count, PB->x, PB->y, mask )==0) {
  380.            goto CleanUp;
  381.         }
  382.         /* depth buffering w/ stencil */
  383.         gl_depth_stencil_pixels( ctx, PB->count, PB->x, PB->y, PB->z, mask );
  384.      }
  385.      else if (ctx->Depth.Test) {
  386.         /* regular depth testing */
  387.         (*ctx->Driver.DepthTestPixels)( ctx, PB->count, PB->x, PB->y, PB->z, mask );
  388.      }
  389.          
  390.          if (ctx->RasterMask & NO_DRAW_BIT) {
  391.             goto CleanUp;
  392.          }
  393.  
  394.          /* write pixels */
  395.          (*ctx->Driver.Index)( ctx, PB->index );
  396.          (*ctx->Driver.WriteMonoindexPixels)( ctx, PB->count, PB->x, PB->y, mask );
  397.  
  398.          if (ctx->RasterMask & FRONT_AND_BACK_BIT) {
  399.             /*** Also write to back buffer ***/
  400.             (*ctx->Driver.SetBuffer)( ctx, GL_BACK );
  401.             (*ctx->Driver.WriteMonoindexPixels)( ctx, PB->count, PB->x, PB->y, mask );
  402.             (*ctx->Driver.SetBuffer)( ctx, GL_FRONT );
  403.          }
  404.          /*** ALL DONE ***/
  405.       }
  406.    }
  407.  
  408. CleanUp:
  409.    PB->count = 0;
  410.    UNDEFARRAY(mask);
  411.    UNDEFARRAY(rsave);
  412.    UNDEFARRAY(gsave);
  413.    UNDEFARRAY(bsave);
  414.    UNDEFARRAY(asave);
  415. }
  416.  
  417.  
  418.